package com.coolingme.springcloud.sentinel;

import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientAssignConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import java.util.List;

/**
 * 通过Sentinel的InitFuc SPI实现接口的扩展，配置限流规则
 * <p>
 * 集群客户端机器配置
 *
 * @author wangyue
 * @date 2022/10/18 16:15
 */
public class FlowRuleClusterClientInitFunc implements InitFunc {

    private final String nacosAddress = "192.168.112.128:8848";
    private final String groupId      = "SENTINEL_GROUP";

    /**
     * 集群的namespace，和dataIdSuffix拼接获取完整的dataId
     */
    private final String appName = "sentinel-token-server";

    private final String dataIdSuffix = "-flow-rules";

    /**
     * 集群服务端IP
     */
    private final String clusterServerHost = "192.168.3.21";

    /**
     * 集群服务端端口
     */
    private final Integer clusterServerPort = 9999;

    /**
     * 请求超时时长
     */
    private final Integer requestTimeOut = 20000;


    @Override
    public void init() throws Exception {
        System.out.println("*********Sentinel InitFunc SPI (Cluster Client)**********");
        loadClusterConfig();
        registerFlowRule();
    }

    private void loadClusterConfig() {
        ClusterClientAssignConfig assignConfig = new ClusterClientAssignConfig();
        //放到配置中心
        assignConfig.setServerHost(clusterServerHost);
        assignConfig.setServerPort(clusterServerPort);
        ClusterClientConfigManager.applyNewAssignConfig(assignConfig);

        ClusterClientConfig clientConfig = new ClusterClientConfig();
        //放到配置中心
        clientConfig.setRequestTimeout(requestTimeOut);
        ClusterClientConfigManager.applyNewConfig(clientConfig);
    }

    private void registerFlowRule() {
        ReadableDataSource<String, List<FlowRule>> flowRuleDs =
                new NacosDataSource<>(nacosAddress, groupId, appName + dataIdSuffix,
                        source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                        }));
        FlowRuleManager.register2Property(flowRuleDs.getProperty());
    }

}
